package main.java.FSMDE.views;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

import main.java.FSMDE.controllers.IInterfaceController;
import main.java.FSMDE.controllers.InterfaceController;
import main.java.FSMDE.models.ComponentCollection;
import main.java.FSMDE.models.InterfaceGraphType;
import main.java.FSMDE.models.InterfaceType;
import main.java.FSMDE.models.Operations;


import com.jgoodies.forms.factories.*;
import com.jgoodies.forms.layout.*;

public class InterfaceView implements IInterfaceView {
	private IInterfaceController interfaceController;
	private ITransitionView transitionView;
	private static String CREATION_TITLE = "Interface Creation";
	private static String UPDATE_TITLE = "Interface Update";

	private JFrame frame1;
	private JLabel interfaceNameText;
	private JTextField interfaceName;
	private JLabel interfaceTypeText;
	@SuppressWarnings("rawtypes")
	private JComboBox interfaceTypeComboBox;
	private JPanel panel1;
	private JButton createButton;
	private JButton cancelButton;
	private IComponentView componentView;
	private JRadioButton normalInterface;
	private JRadioButton startInterface;
	private JRadioButton endInterface;
	private Object operation;

	public InterfaceView() {
		this.operation = Operations.None;
		initComponents();
		createButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent actionEvent) {
				createInterface();
			}
		});

		cancelButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent actionEvent) {
				cancelAction();
			}
		});

	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	private void initComponents() {

		frame1 = new JFrame();
		frame1.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
		frame1.setUndecorated(true);
		frame1.getRootPane().setWindowDecorationStyle(
				JRootPane.INFORMATION_DIALOG);
		interfaceNameText = new JLabel();
		interfaceName = new JTextField();
		interfaceTypeText = new JLabel();
		interfaceTypeComboBox = new JComboBox(InterfaceType.values());
		panel1 = new JPanel();
		createButton = new JButton("Finish");
		cancelButton = new JButton("Cancel");
		normalInterface = new JRadioButton("Normal");
		startInterface = new JRadioButton("Start");
		endInterface = new JRadioButton("End");

		// ======== frame1 ========
		{
			frame1.setTitle(CREATION_TITLE);
			Container frame1ContentPane = frame1.getContentPane();
			frame1ContentPane.setLayout(new FormLayout(
					"74*(default, $lcgap), default",
					"89*(default, $lgap), default"));

			// ---- Interface name ----
			interfaceNameText.setText("Name: ");
			interfaceNameText.setLabelFor(interfaceName);
			frame1ContentPane.add(interfaceNameText, CC.xy(5, 3));
			frame1ContentPane.add(interfaceName, CC.xywh(9, 3, 41, 1));

			// ---- Interface type ----
			interfaceTypeText.setText("Type");
			interfaceTypeText.setLabelFor(interfaceTypeComboBox);
			frame1ContentPane.add(interfaceTypeText, CC.xy(5, 7));
			frame1ContentPane.add(interfaceTypeComboBox, CC.xy(9, 7));

			// ---- Interface Start/End ----
			normalInterface.setSelected(true);
			frame1ContentPane.add(normalInterface, CC.xywh(50, 7, 30, 1));
			frame1ContentPane.add(startInterface, CC.xywh(80, 7, 30, 1));
			frame1ContentPane.add(endInterface, CC.xywh(110, 7, 30, 1));
			ButtonGroup bg = new ButtonGroup();
			bg.add(normalInterface);
			bg.add(startInterface);
			bg.add(endInterface);

			// ======== panel1 ========
			{

				GroupLayout panel1Layout = new GroupLayout(panel1);
				panel1.setLayout(panel1Layout);
				panel1Layout
						.setHorizontalGroup(panel1Layout.createParallelGroup()
								.addGap(0, 1745, Short.MAX_VALUE));
				panel1Layout
						.setVerticalGroup(panel1Layout.createParallelGroup()
								.addGap(0, 1269, Short.MAX_VALUE));
			}
			frame1ContentPane.add(panel1, CC.xywh(5, 11, 145, 169));

			frame1ContentPane.add(cancelButton, CC.xywh(115, 179, 29, 1));
			frame1ContentPane.add(createButton, CC.xy(149, 179));
			frame1.pack();
			frame1.setLocationRelativeTo(frame1.getOwner());

		}
	}

	private void createInterface() {
		if (interfaceController.addInterface()) {
			this.frame1.setVisible(false);
		} else {
			showWrongInterfaceNameDialog();
		}
	}

	private void cancelAction() {
		interfaceController.cancelPendingInterfaceAction();
		this.frame1.setVisible(false);
	}

	private void showWrongInterfaceNameDialog() {
		if (interfaceName.getText().equals("")) {
			JOptionPane.showMessageDialog(null,
					"An interface must have a name, please complete it.",
					"Invalid Interface Name", JOptionPane.QUESTION_MESSAGE);
		} else
			JOptionPane
					.showMessageDialog(
							null,
							this.interfaceName.getText()
									+ " already exists as an interface name on this project, please change it.",
							"Invalid Interface Name",
							JOptionPane.QUESTION_MESSAGE);
	}

	@Override
	public ITransitionView getTransitionView() {
		return this.transitionView;
	}

	@Override
	public InterfaceType getInterfaceType() {
		return (InterfaceType) this.interfaceTypeComboBox
				.getItemAt(this.interfaceTypeComboBox.getSelectedIndex());
	}

	@Override
	public void setInterfaceType(InterfaceType type) {
		this.interfaceTypeComboBox.setSelectedItem(type);
	}

	@Override
	public void setInterfaceName(String name) {
		this.interfaceName.setText(name);
	}

	@Override
	public void showView() {
		if (this.operation == Operations.Updating) {
			cancelButton.setVisible(false);
			this.frame1.setTitle(UPDATE_TITLE);
		}
		this.frame1.setVisible(true);
	}

	@Override
	public void setController(InterfaceController interfaceController) {
		this.interfaceController = interfaceController;
	}

	@Override
	public void addTransitionView(ITransitionView transitionsView) {
	}

	@Override
	public void addComponentView(IComponentView componentView) {
		this.componentView = componentView;
		frame1.remove(panel1);
		Container frame1ContentPane = frame1.getContentPane();
		frame1ContentPane.add((Component) componentView.getInternalFrame(),
				CC.xywh(5, 11, 145, 169));

	}

	@Override
	public void setModeUpdating() {
		this.frame1.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
	}

	@Override
	public String getInterfaceName() {
		return interfaceName.getText();
	}

	@Override
	public InterfaceGraphType getGraphType() {

		if (startInterface.isSelected())
			return InterfaceGraphType.Starting_interface;
		if (endInterface.isSelected())
			return InterfaceGraphType.Ending_interface;
		return InterfaceGraphType.Normal;
	}

	@Override
	public void setInterfaceGraphType(InterfaceGraphType graphType) {
		switch (graphType) {
		case Starting_interface: {
			startInterface.setSelected(true);
			normalInterface.setSelected(false);
			endInterface.setSelected(false);
			break;
		}
		case Ending_interface: {
			endInterface.setSelected(true);
			normalInterface.setSelected(false);
			startInterface.setSelected(false);
			break;
		}
		default: {
			normalInterface.setSelected(true);
			startInterface.setSelected(false);
			endInterface.setSelected(false);
		}
		}
	}

	@Override
	public void setComponents(ComponentCollection components) {
		this.componentView.setComponents(components);
	}

	@Override
	public void setOperation(Operations operation) {
		this.operation = operation;
	}

}
